package gui;

import dto.CoberturaDTO;
import dto.HorarioDTO;
import dto.MedicoDTO;
import java.awt.Component;
import java.awt.Frame;
import java.sql.SQLException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableModel;
import logic.Cobertura;
import logic.Especialidad;
import logic.Horario;
import logic.Medico;
import logic.ObraSocial;
import logic.ObraSocialPlan;
import logic.Turno;
import util.InputHelper;

/**
 *
 * @author lucifer
 */
public class MedicoGrepPanel extends javax.swing.JPanel implements Slave {

  private Master master;

  public void SetMaster(Master master) {
    this.master = master;
  }

  public void SetModeActions() {
    ((JFrame) master).setTitle("Médicos - Senzu");
  }

  private ArrayList<Integer> mIDs;
  private Medico medicoSeleccionado;

  public MedicoGrepPanel(Master master) {
    SetMaster(master);

    initComponents();
    preBusqueda();
  }

  public Medico MedicoSeleccionado() {
    return medicoSeleccionado;
  }

  private String getStringEspecialidadMedica(int idEspecialidad) {
    String especialidad = "no especificada";
    try {
      especialidad = Especialidad.SearchByID(idEspecialidad).getNombre();
    } catch (Exception e) {
      System.out.printf("?especialidad fail\n");
    }
    return especialidad;
  }

  private void setAttributes(MedicoDTO m) {
    medicojLabel1.setText(String.format("<html><b>Dr. %s %s</b></html>", m.getNombre(), m.getApellido()));
    especialidadjLabel1.setText(getStringEspecialidadMedica(m.getIdEspecialidad()));
    matriculajLabel1.setText(m.getMatricula());
    telLineajLabel1.setText(m.getTelLinea());
    telCelularjLabel1.setText(m.getCelular());
    try {
      updateHorarios(Horario.SearchByMedicoID(m.getId()));
      updateCoberturas(Cobertura.SearchByMedicoID(m.getId()));
    } catch (Exception e) {
      System.out.printf("?horarios/coberturas db issue\n");
    }
  }

  private void cleanAll() throws SQLException {
    medicojLabel1.setText("<html><b>Médico no seleccionado</b></html>");
    especialidadjLabel1.setText("");
    matriculajLabel1.setText("");
    telLineajLabel1.setText("");
    telCelularjLabel1.setText("");
    updateHorarios(new ArrayList<HorarioDTO>());
    updateCoberturas(new ArrayList<CoberturaDTO>());
  }

  private void acceptMedicoSelection() {
    try {
      int id = mIDs.get(buscarjTable.getSelectedRow());
      medicoSeleccionado = new Medico(Medico.SearchByID(id));
    } catch (Exception e) {
      JOptionPane.showMessageDialog(this, "No seleccionó ningún médico. Seleccione un médico, por favor.", "Atención!", JOptionPane.WARNING_MESSAGE);
      return;
    }

    master.TurnoGrepPanel().SetMedico(medicoSeleccionado);
    try {
      master.TurnoGrepPanel().UpdateMedicoData();
    } catch (SQLException e) {
      System.out.printf("?medico data issue\n");
    }
    master.ShowSlave(master.TurnoGrepPanel());
  }

  private void preBusqueda() {
    try {
      updateTabla(Medico.All());
    } catch (SQLException e) {
      System.out.printf("?m:database connection failed\n");
    }
  }

  private void updateTabla(ArrayList<MedicoDTO> dtos) {
    DefaultTableModel m = new DefaultTableModel();
    m.addColumn("Apellido");
    m.addColumn("Nombre");
    m.addColumn("Especialidad");

    mIDs = new ArrayList<>();
    for (MedicoDTO dto : dtos) {
      mIDs.add(dto.getId());
      m.addRow(
        new Object[]{
          dto.getApellido(),
          dto.getNombre(),
          getStringEspecialidadMedica(dto.getIdEspecialidad())
        }
      );
    }

    buscarjTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    buscarjTable.setModel(m);
  }

  private void updateHorarios(ArrayList<HorarioDTO> dtos) {
    DefaultTableModel m = new DefaultTableModel();
    m.addColumn("Día");
    m.addColumn("Desde las");
    m.addColumn("Hasta las");

    for (HorarioDTO dto : dtos) {
      m.addRow(
        new Object[]{
          InputHelper.DayConverter(dto.getDia()),
          dto.getHoraDesde(),
          dto.getHoraHasta()
        }
      );
    }
    horariosjTable.setColumnSelectionAllowed(false);
    horariosjTable.setRowSelectionAllowed(false);
    horariosjTable.setModel(m);
  }

  private void updateCoberturas(ArrayList<CoberturaDTO> dtos) throws SQLException {
    DefaultTableModel m = new DefaultTableModel();
    m.addColumn("Obra Social");
    m.addColumn("Plan");

    for (CoberturaDTO dto : dtos) {
      if (dto.getIdObraSocial() == 0) {
        continue;
      }
      m.addRow(
        new Object[]{
          ObraSocial.SearchByID(dto.getIdObraSocial()).getNombre(),
          ObraSocialPlan.SearchByID(dto.getIdPlanObraSocial()).getNombre()
        }
      );
    }
    coberturasjTable.setColumnSelectionAllowed(false);
    coberturasjTable.setRowSelectionAllowed(false);
    coberturasjTable.setModel(m);
  }

  /**
   * This method is called from within the constructor to initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is always
   * regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    buscarjLabel = new javax.swing.JLabel();
    buscarjTextField = new javax.swing.JTextField();
    buscarjScrollPane = new javax.swing.JScrollPane();
    buscarjTable = new JTable() {
      public boolean isCellEditable(int i, int j) {
        return false;
      }
    };
    aceptarjButton = new javax.swing.JButton();
    generarTurnosjButton = new javax.swing.JButton();
    medicoInfojTabbedPane = new javax.swing.JTabbedPane();
    horariosjScrollPane = new javax.swing.JScrollPane();
    horariosjTable = new JTable() {
      public boolean isCellEditable(int i, int j) {
        return false;
      }
    };
    coberturasjScrollPane = new javax.swing.JScrollPane();
    coberturasjTable = new JTable() {
      public boolean isCellEditable(int i, int j) {
        return false;
      }
    };
    medicojLabel1 = new javax.swing.JLabel();
    medicojLabel = new javax.swing.JLabel();
    especialidadjLabel = new javax.swing.JLabel();
    especialidadjLabel1 = new javax.swing.JLabel();
    matriculajLabel1 = new javax.swing.JLabel();
    matriculajLabel = new javax.swing.JLabel();
    telLineajLabel = new javax.swing.JLabel();
    telLineajLabel1 = new javax.swing.JLabel();
    telCelularjLabel1 = new javax.swing.JLabel();
    telCelularjLabel = new javax.swing.JLabel();

    buscarjLabel.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
    buscarjLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/gui/search.png"))); // NOI18N
    buscarjLabel.setMaximumSize(new java.awt.Dimension(25, 27));
    buscarjLabel.setMinimumSize(new java.awt.Dimension(25, 27));
    buscarjLabel.setPreferredSize(new java.awt.Dimension(25, 27));

    buscarjTextField.setToolTipText("Se pueden buscar médicos por nombre ó apellido..");
    buscarjTextField.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseClicked(java.awt.event.MouseEvent evt) {
        buscarjTextFieldMouseClicked(evt);
      }
    });
    buscarjTextField.addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyReleased(java.awt.event.KeyEvent evt) {
        buscarjTextFieldKeyReleased(evt);
      }
    });

    buscarjTable.setModel(new javax.swing.table.DefaultTableModel(
      new Object [][] {

      },
      new String [] {
        "Apellido", "Nombre", "Especialidad"
      }
    ) {
      Class[] types = new Class [] {
        java.lang.String.class, java.lang.String.class, java.lang.String.class
      };
      boolean[] canEdit = new boolean [] {
        false, false, false
      };

      public Class getColumnClass(int columnIndex) {
        return types [columnIndex];
      }

      public boolean isCellEditable(int rowIndex, int columnIndex) {
        return canEdit [columnIndex];
      }
    });
    buscarjTable.getTableHeader().setReorderingAllowed(false);
    buscarjTable.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseClicked(java.awt.event.MouseEvent evt) {
        buscarjTableMouseClicked(evt);
      }
    });
    buscarjTable.addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyReleased(java.awt.event.KeyEvent evt) {
        buscarjTableKeyReleased(evt);
      }
    });
    buscarjScrollPane.setViewportView(buscarjTable);

    aceptarjButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/gui/go_back.png"))); // NOI18N
    aceptarjButton.setText("Volver a Turnos");
    aceptarjButton.setMaximumSize(new java.awt.Dimension(224, 27));
    aceptarjButton.setMinimumSize(new java.awt.Dimension(224, 27));
    aceptarjButton.setPreferredSize(new java.awt.Dimension(224, 27));
    aceptarjButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        aceptarjButtonActionPerformed(evt);
      }
    });

    generarTurnosjButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/gui/generar_turnos.png"))); // NOI18N
    generarTurnosjButton.setText("Habilitar turnos libres");
    generarTurnosjButton.setMaximumSize(new java.awt.Dimension(224, 27));
    generarTurnosjButton.setMinimumSize(new java.awt.Dimension(224, 27));
    generarTurnosjButton.setPreferredSize(new java.awt.Dimension(224, 27));
    generarTurnosjButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        generarTurnosjButtonActionPerformed(evt);
      }
    });

    medicoInfojTabbedPane.setMinimumSize(new java.awt.Dimension(372, 254));
    medicoInfojTabbedPane.setPreferredSize(new java.awt.Dimension(372, 254));

    horariosjTable.setModel(new javax.swing.table.DefaultTableModel(
      new Object [][] {

      },
      new String [] {
        "Día", "Desde las", "Hasta las"
      }
    ) {
      Class[] types = new Class [] {
        java.lang.String.class, java.lang.String.class, java.lang.String.class
      };
      boolean[] canEdit = new boolean [] {
        false, false, false
      };

      public Class getColumnClass(int columnIndex) {
        return types [columnIndex];
      }

      public boolean isCellEditable(int rowIndex, int columnIndex) {
        return canEdit [columnIndex];
      }
    });
    horariosjTable.getTableHeader().setReorderingAllowed(false);
    horariosjScrollPane.setViewportView(horariosjTable);

    medicoInfojTabbedPane.addTab("Horarios de Atención", horariosjScrollPane);

    coberturasjTable.setModel(new javax.swing.table.DefaultTableModel(
      new Object [][] {

      },
      new String [] {
        "Obra Social", "Plan"
      }
    ) {
      Class[] types = new Class [] {
        java.lang.String.class, java.lang.String.class
      };
      boolean[] canEdit = new boolean [] {
        false, false
      };

      public Class getColumnClass(int columnIndex) {
        return types [columnIndex];
      }

      public boolean isCellEditable(int rowIndex, int columnIndex) {
        return canEdit [columnIndex];
      }
    });
    coberturasjTable.getTableHeader().setReorderingAllowed(false);
    coberturasjScrollPane.setViewportView(coberturasjTable);

    medicoInfojTabbedPane.addTab("Coberturas", coberturasjScrollPane);

    medicojLabel1.setText("<html><b>Médico no seleccionado</b></html>");

    especialidadjLabel.setText("Especialidad:");

    especialidadjLabel1.setText("-");

    matriculajLabel1.setText("-");

    matriculajLabel.setText("Matrícula:");

    telLineajLabel.setText("Teléfono de línea:");

    telLineajLabel1.setText("-");

    telCelularjLabel1.setText("-");

    telCelularjLabel.setText("Teléfono celular:");

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
    this.setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
          .addGroup(layout.createSequentialGroup()
            .addComponent(buscarjLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(buscarjTextField))
          .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addGap(111, 111, 111)
            .addComponent(medicojLabel)
            .addGap(190, 190, 190))
          .addComponent(buscarjScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 440, Short.MAX_VALUE))
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(layout.createSequentialGroup()
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
              .addComponent(medicoInfojTabbedPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
              .addComponent(generarTurnosjButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
              .addComponent(aceptarjButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addGap(0, 0, Short.MAX_VALUE))
          .addGroup(layout.createSequentialGroup()
            .addGap(31, 31, 31)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addComponent(medicojLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
              .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                  .addComponent(telCelularjLabel)
                  .addComponent(telLineajLabel)
                  .addComponent(especialidadjLabel)
                  .addComponent(matriculajLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                  .addComponent(especialidadjLabel1)
                  .addComponent(matriculajLabel1)
                  .addComponent(telLineajLabel1)
                  .addComponent(telCelularjLabel1))))
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addGap(0, 0, 0)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(generarTurnosjButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
            .addComponent(buscarjLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addComponent(buscarjTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
          .addGroup(layout.createSequentialGroup()
            .addGap(18, 18, 18)
            .addComponent(medicojLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(18, 18, 18)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
              .addComponent(especialidadjLabel)
              .addComponent(especialidadjLabel1))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
              .addComponent(matriculajLabel)
              .addComponent(matriculajLabel1))
            .addGap(18, 18, 18)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
              .addComponent(telLineajLabel)
              .addComponent(telLineajLabel1))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
              .addComponent(telCelularjLabel)
              .addComponent(telCelularjLabel1))
            .addGap(18, 18, 18)
            .addComponent(medicoInfojTabbedPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(aceptarjButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
          .addGroup(layout.createSequentialGroup()
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(buscarjScrollPane)))
        .addGap(0, 0, 0)
        .addComponent(medicojLabel)
        .addGap(0, 0, 0))
    );
  }// </editor-fold>//GEN-END:initComponents

  private void buscarjTextFieldMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_buscarjTextFieldMouseClicked
    buscarjTextField.selectAll();
  }//GEN-LAST:event_buscarjTextFieldMouseClicked

  private void buscarjTextFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_buscarjTextFieldKeyReleased
    String itemToSearch =  buscarjTextField.getText();
    ArrayList<MedicoDTO> medicoDTOs;
    try {
      medicoDTOs = Medico.SearchByNombreApellido(itemToSearch);
      updateTabla(medicoDTOs);
      if (medicoDTOs.isEmpty() || buscarjTable.getSelectedRow() == -1) {
        cleanAll();
      }
      if (medicoDTOs.size() == 1) {
        buscarjTable.setRowSelectionInterval(0, 0);
        buscarjTableMouseClicked(null);
      }
    } catch (SQLException e) {
      JOptionPane.showMessageDialog(this, InputHelper.PanicMessage, "ERROR! Esta aplicación se cerrará", JOptionPane.ERROR_MESSAGE);
      System.exit(66);
    }
  }//GEN-LAST:event_buscarjTextFieldKeyReleased

  private void buscarjTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_buscarjTableMouseClicked
    int sel = buscarjTable.getSelectedRow();
    if (sel == -1) {
      return;
    }

    int id = mIDs.get(sel);
    try {
      setAttributes(Medico.SearchByID(id));
    } catch (SQLException e) {
      System.out.printf("?id not found\n");
    }
  }//GEN-LAST:event_buscarjTableMouseClicked

  private void aceptarjButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_aceptarjButtonActionPerformed
    acceptMedicoSelection();
  }//GEN-LAST:event_aceptarjButtonActionPerformed

  private void generarTurnosjButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_generarTurnosjButtonActionPerformed
    int sel = buscarjTable.getSelectedRow();
    if (sel == -1) {
      JOptionPane.showMessageDialog(this, "No seleccionó ningún médico. Seleccione un médico, por favor.", "Atención!", JOptionPane.WARNING_MESSAGE);
      return;
    }

    int id = mIDs.get(sel);
    try {
      MedicoDTO m = Medico.SearchByID(id);
      String medico = String.format("%s %s", m.getNombre(), m.getApellido());

      // En Java, `null` es un eufemismo para `no sé qué corno va a hacer ahora'.
      LocalDate fecha = null;
      LocalDateTime lastTurno = Turno.UltimoTurnoGeneradoDelMedico(id);
      if (lastTurno != null) {
        fecha = lastTurno.toLocalDate();
      }

      GenerarTurnosLibresDialog g = new GenerarTurnosLibresDialog((Frame) master, true, id, medico, fecha);
      g.setLocationRelativeTo((Component) master);
      g.setVisible(true);

      if (g.getReturnStatus() == 1) {
        JOptionPane.showMessageDialog(
          this,
          String.format("Se habilitaron exitosamente los turnos libres del médico %s.", medico),
          "Éxito: Habilitación de turnos libres",
          JOptionPane.INFORMATION_MESSAGE
        );
      }

    } catch (SQLException e) {
      System.out.printf("?generar turnos issue\n");
    }
  }//GEN-LAST:event_generarTurnosjButtonActionPerformed

  private void buscarjTableKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_buscarjTableKeyReleased
    buscarjTableMouseClicked(null);
  }//GEN-LAST:event_buscarjTableKeyReleased

  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JButton aceptarjButton;
  private javax.swing.JLabel buscarjLabel;
  private javax.swing.JScrollPane buscarjScrollPane;
  private javax.swing.JTable buscarjTable;
  private javax.swing.JTextField buscarjTextField;
  private javax.swing.JScrollPane coberturasjScrollPane;
  private javax.swing.JTable coberturasjTable;
  private javax.swing.JLabel especialidadjLabel;
  private javax.swing.JLabel especialidadjLabel1;
  private javax.swing.JButton generarTurnosjButton;
  private javax.swing.JScrollPane horariosjScrollPane;
  private javax.swing.JTable horariosjTable;
  private javax.swing.JLabel matriculajLabel;
  private javax.swing.JLabel matriculajLabel1;
  private javax.swing.JTabbedPane medicoInfojTabbedPane;
  private javax.swing.JLabel medicojLabel;
  private javax.swing.JLabel medicojLabel1;
  private javax.swing.JLabel telCelularjLabel;
  private javax.swing.JLabel telCelularjLabel1;
  private javax.swing.JLabel telLineajLabel;
  private javax.swing.JLabel telLineajLabel1;
  // End of variables declaration//GEN-END:variables
}
